﻿/*
' Copyright (c) 2013  DotNetNuke Corporation
'  All rights reserved.
' 
' THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
' TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
' THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
' CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
' DEALINGS IN THE SOFTWARE.
' 
*/

using System;
using System.Web.UI.WebControls;
using DotNetNuke.Security;
using DotNetNuke.Services.Exceptions;
using DotNetNuke.Entities.Modules;
using DotNetNuke.Entities.Modules.Actions;
using DotNetNuke.Services.Localization;

using System.Linq;
using System.Collections;
using DotNetNuke.Security.Roles;
using DotNetNuke.Modules.mwOrgChart.Components.Business;
using System.Collections.Generic;
using DotNetNuke.Web.UI;
using Telerik.Web.UI;
using DotNetNuke.Web.UI.WebControls;

using DotNetNuke.Common.Utilities;
using DotNetNuke.Entities.Users;
using System.Web.UI;
//using DotNetNuke.Entities.Users.Internal;
//using DotNetNuke.Web;
//using DotNetNuke.Framework;
//using DotNetNuke.Security.Roles.Internal;
//using DotNetNuke.UI.Skins.Controls;
//using DotNetNuke.UI.Utilities;


//only for test
using DotNetNuke.Modules.mwCompanyManager.Components.Business;

namespace DotNetNuke.Modules.mwOrgChart
{
    /// -----------------------------------------------------------------------------
    /// <summary>
    /// The View class displays the content
    /// 
    /// Typically your view control would be used to display content or functionality in your module.
    /// 
    /// View may be the only control you have in your project depending on the complexity of your module
    /// 
    /// Because the control inherits from mwOrgChartModuleBase you have access to any custom properties
    /// defined there, as well as properties from DNN such as PortalId, ModuleId, TabId, UserId and many more.
    /// 
    /// </summary>
    /// -----------------------------------------------------------------------------


    class TextBoxTemplate : ITemplate
    {
        public string subtitle { get; set; }

        public void InstantiateIn(Control container)
        {
            Label label1 = new Label();
            label1.ID = "ItemLabel";
            label1.Text = "Text";
            label1.CssClass = "name";
            label1.Font.Size = 10;
            label1.Font.Bold = true;
            label1.DataBinding += new EventHandler(label1_DataBinding);

            Label label2 = new Label();
            label2.ID = "ItemLabel2";
            label2.CssClass = "details";
            label2.Text = this.subtitle;
            //label2.DataBinding += new EventHandler(label1_DataBinding);

            if ((label1.Text != null) || (label2.Text != null))
            {
                container.Controls.Add(new Literal { Text = "<div class=\"node-user-data\">" });
                container.Controls.Add(label1);
                container.Controls.Add(label2);
                container.Controls.Add(new Literal { Text = "</div>" });
            }
        }

        private void label1_DataBinding(object sender, EventArgs e)
        {
            Label target = (Label)sender;
            RadTreeNode node = (RadTreeNode)target.BindingContainer;
            string nodeText = (string)DataBinder.Eval(node, "Text");
            target.Text = nodeText;
        }
    }
    
    public partial class View : mwOrgChartModuleBase, IActionable
    {

#region Private Members
      
        private int HierarchyID
        {
            get
            {
                if (Settings.Contains("mwHierarchyID"))
                {
                    return int.Parse(Settings["mwHierarchyID"].ToString());
                }

                return 0;
            }
        }

        private enum Position
        {
            Child,
            Below,
            Above
        }

        public enum HierarchyMoveType
        {
            Up,
            Down,
            Top,
            Bottom,
            Promote,
            Demote
        }

        protected string GetProfileImage(int userId, int width, int height)
        {
            return Page.ResolveUrl("~/profilepic.ashx?userid=" + userId.ToString() + "&w=" + width.ToString() + "&h=" + height.ToString());
        }

#endregion

#region Icons Properties        

        private string IconHome
        {
            get
            {
                return TemplateSourceDirectory + "/images/Icon_Home.png";
            }
        }

        private string IconOffice
        {
            get
            {
                return TemplateSourceDirectory + "/images/mwCompanyManager32.png";
            }
        }

        private string IconPageDisabled
        {
            get
            {
                return TemplateSourceDirectory + "/images/Icon_Disabled.png";
            }
        }
        
        private string IconPageHidden
        {
            get
            {
                return TemplateSourceDirectory + "/images/Icon_Hidden.png";
            }
        }

        private string SelectedNode
        {
            get { return (string)ViewState["SelectedNode"]; }
            set { ViewState["SelectedNode"] = value; }
        }

        private string AllUsersIcon
        {
            get
            {
                return TemplateSourceDirectory + "/images/Folders-OS-Groups-Metro-icon.png";
            }
        }

        private string GetNodeStatusIcon(mwHierarchy node)
        {
            if (node.Status == HierarchyStatus.Disabled)
            {
                return "<img src=\"" + IconPageDisabled + "\" class=\"statusicon\" />";
            }

            if (node.Status == HierarchyStatus.Pending)
            {
                return "<img src=\"" + IconPageHidden + "\" class=\"statusicon\" />";
            }

            return "";
        }

        private string GetNodeTypeIcon(int nodeType)
        {
            if (nodeType == 1)
            {
                return "<img src=\"" + AllUsersIcon + "\" class=\"icontype\" />";
            }

            if (nodeType == 2)
            {
                return "<img src=\"" + IconOffice + "\" class=\"icontype\" />"; 
            }

            return "";
        }

        private string GetNodeIcon(mwHierarchy node, int nodeId = 0)
        {
            if (nodeId == node.NodeID)
            {
                return IconHome;
            }

            return AllUsersIcon;
        }

#endregion

        protected override void OnInit(EventArgs e)
        {
            base.OnInit(e);

            //tvMain.NodeClick += CtlPagesNodeClick;
            //tvMain.ContextMenuItemClick += CtlPagesContextMenuItemClick;
            //tvMain.NodeEdit += CtlPagesNodeEdit;

            if (PortalSecurity.IsInRole(PortalSettings.AdministratorRoleName))
            {
                tvMain.EnableDragAndDrop = true;
                tvMain.EnableDragAndDropBetweenNodes = true;
                tvMain.NodeDrop += CtlNodeDrop;
            }
            else
            {
                tvMain.EnableDragAndDrop = false;
                tvMain.EnableDragAndDropBetweenNodes = false;
            }

            //cmdExpandTree.Click += OnExpandTreeClick;
            //grdModules.NeedDataSource += GrdModulesNeedDataSource;
            //tvMain.NodeExpand += CtlPagesNodeExpand;
            //btnBulkCreate.Click += OnCreatePagesClick;
            //cmdUpdate.Click += CmdUpdateClick;

            //jQuery.RequestDnnPluginsRegistration();

            //ClientAPI.RegisterClientReference(Page, ClientAPI.ClientNamespaceReferences.dnn_dom);
            //ClientAPI.RegisterClientScriptBlock(Page, "dnn.controls.js");
            //dgPermissions.RegisterScriptsForAjaxPanel();
        }

        protected void Page_Load(object sender, EventArgs e)
        {

            //module navigation
            lbNewRelation.PostBackUrl = DotNetNuke.Common.Globals.NavigateURL(PortalSettings.ActiveTab.TabID, "NodeRelation", "mid=" + ModuleId.ToString());
            lbNewRelation.Attributes.Add("onclick", "return " + UrlUtils.PopUpUrl(lbNewRelation.PostBackUrl, this, PortalSettings, true, false));

            btnNewNode.PostBackUrl = DotNetNuke.Common.Globals.NavigateURL(PortalSettings.ActiveTab.TabID, "Node", "mid=" + ModuleId.ToString());
            btnNewNode.Attributes.Add("onclick", "return " + UrlUtils.PopUpUrl(btnNewNode.PostBackUrl, this, PortalSettings, true, false));

            try
            {
                if (!Page.IsPostBack)
                {
                    BindTree();
                }
            }
            catch (Exception exc)
            {
                Exceptions.ProcessModuleLoadException(this, exc);
            }
        }
       
        private void BindTree(int RootRoleID = 0)
        {     
            tvMain.Nodes.Clear();

            RadTreeNode treeNode = new RadTreeNode();
            treeNode.Text = "HierarchyName";
            treeNode.Value = "0";

            IEnumerable<mwHierarchy> colFolders = mwHierarchyController.GetHierarchy(HierarchyID);

            //var offices = OfficeController.GetCurrentOffices(479);
            //var nodeRelations = mwHierarchyRelationsController.GetHierarchyRelations(0); 


            BuildNodesTree(colFolders, treeNode, RootRoleID);

            tvMain.Nodes.Add(treeNode);
            tvMain.DataBind();

            if (RootRoleID == 0)
            {
                tvMain.Nodes[0].Selected = true;
                tvMain.SelectedNode.Expanded = true;               
                //tvMain.ExpandAllNodes();
            }    
        }

        public void BuildNodesTree(IEnumerable<mwHierarchy> list, RadTreeNode parentNode, int RootNodeId = 0)
        {
           //if(parentNode == null, x.ParentID == 0, x.ParentID = Int.Parse(parentNode.Value)));

            var nodes = list.Where(x => x.ParentID == int.Parse(parentNode.Value));
            var nodeRelations = mwHierarchyRelationsController.GetHierarchyRelations(PortalId, UserId);

            foreach (var node in nodes) 
            {            
                var newNode = new RadTreeNode
                {
                    Text = string.Format("{0} {1}", node.Name, GetNodeStatusIcon(node)),
                    Value = Convert.ToString(node.NodeID),
                    AllowEdit = true,
                    ImageUrl = GetNodeIcon(node, RootNodeId)
                };

                /*
                // -----------------------------------------
                // Mapping roles to entities
                //IEnumerable<mwHierarchyRelations> nodeRelations = mwHierarchyRelationsController.GetHierarchyRelationsByNode(node.NodeID);

                //---- Add Office Child Node
                //if (hnode.OfficeID > 0)
                //{
                var uffici = OfficeController.GetCurrentOfficesByNode(479, node.NodeID);
                IList<RadTreeNode> nds = new List<RadTreeNode>();

                foreach (var item in uffici)
                {
                    var rtnOfficeRelations = new RadTreeNode
                    {
                        Text = string.Format("{0} {1}", GetNodeTypeIcon(2), item.Name),
                        Value = "O-" + item.OfficeID.ToString(),
                        AllowDrag = false,
                        AllowDrop = false,
                        AllowEdit = false
                    };
                    nds.Add(rtnOfficeRelations);
                }

                newNode.Nodes.AddRange(nds);
                //}
                //---- Office Child Node 


                foreach (var hnode in nodeRelations.Where(X=> X.HNodeID == node.NodeID))
                {
                                 
                    if ((hnode.OfficeID < 1) || (hnode.OfficeID == Null.NullInteger)) 
                    { 
                    
                        //---- Add child user node
                        // Si può aggiungere un utente solo se If OfficeId == null
                    
                        //3 If usertype = dnnuser
                        UserInfo user = UserController.GetUserById(PortalId, hnode.UserID);
                        string pic = "<img src=\"" + GetProfileImage(user.UserID, 32,32) + "\" />";
                        var rcc = new RoleController();                
                        var textBoxTemplate = new TextBoxTemplate();
                        textBoxTemplate.subtitle = rcc.GetRole(hnode.RoleID, PortalId).RoleName;
                        //3

                        //4 If usertype = other
                        // user = genericUser
                        // textBoxTemplate.subtitle = ???

                        var rtnRelations = new RadTreeNode
                        {
                            NodeTemplate = textBoxTemplate,
                            Text = string.Format("{0} {1} {2}", pic , user.FirstName, user.LastName),
                            Value = "U-" + user.UserID.ToString(),
                            AllowDrag = false,
                            AllowDrop = false,
                            AllowEdit = false
                        };

                        newNode.Nodes.Add(rtnRelations);
                        //---- Child User Node
                    }               
                }
                // ---------------------------------------------------------
                */
                if (parentNode == null) {
                    tvMain.Nodes.Add(newNode);
                } else {
                    parentNode.Nodes.Add(newNode);
                }

                BuildNodesTree(list, newNode);
            }
        }

        public ModuleActionCollection ModuleActions
        {
            get
            {
                var actions = new ModuleActionCollection
                    {
                        {
                            GetNextActionID(), 
                            Localization.GetString("AddNodeRelation.Action", LocalResourceFile), 
                            ModuleActionType.AddContent, 
                            "", 
                            "add.gif", 
                            EditUrl("NodeRelation"), 
                            false,
                            SecurityAccessLevel.Edit, 
                            true, 
                            false
                        },
                        {
                            GetNextActionID(), 
                            Localization.GetString("AddNewNode.Action", LocalResourceFile), 
                            ModuleActionType.AddContent, 
                            "", 
                            "lt.gif", 
                            EditUrl("Node"), 
                            false,
                            SecurityAccessLevel.Edit, 
                            true, 
                            false
                            }
                    };
                return actions;
            }
        }
 
    
        // ListBox Drag And Drop
        [Obsolete("Test iniziale per l'aggiornamento dei nodi tramite drag and drop")]
        protected void RadListBox1_ItemDropped(object sender, RadListBoxDroppedEventArgs e)
        {
            if (e.HtmlElementID == tvMain.ClientID)
            {
                if (tvMain.SelectedNode != null)
                {
                    foreach (DnnListBoxItem item in e.SourceDragItems)
                    {
                        RadTreeNode node = new RadTreeNode();
                        node.Text = item.Text;

                        if (tvMain.SelectedNode.Level == 0)
                        {
                            tvMain.SelectedNode.Nodes.Add(node);
                        }
                        else
                        {
                            tvMain.SelectedNode.InsertAfter(node);
                        }
                    
                        item.Remove();
                    }
                }
            }
        }

        // ----------------------------------------------------
        // TreeView Drag And Drop
        private bool MoveNode(mwHierarchy node, mwHierarchy targetNode, Position position)
        {
            ////Validate Tab Path
            //if (targetTab == null || !IsValidTabPath(tab, Globals.GenerateTabPath((targetTab == null) ? Null.NullInteger : targetTab.TabID, tab.TabName)))
            //{
            //    return false;
            //}

            var orgController = new mwHierarchyController();
            switch (position)
            {
                case Position.Above:
                    orgController.MoveNodeBefore(node, targetNode.NodeID);
                    //ExecuteNonQuery("MoveTabBefore", tabId, beforeTabId, lastModifiedByUserID);
                    break;
                case Position.Below:
                    orgController.MoveNodeAfter(node, targetNode.NodeID);
                    //ExecuteNonQuery("MoveTabAfter", tabId, afterTabId, lastModifiedByUserID);
                    break;
            }

            //ShowSuccessMessage(string.Format(Localization.GetString("TabMoved", LocalResourceFile), tab.TabName));
            return true;
        }
    
        // TreeView Drag And Drop
        private bool MoveNodeToParent(mwHierarchy role, mwHierarchy targetNode)
        {
            ////Validate Tab Path
            //if (!IsValidTabPath(tab, Globals.GenerateTabPath((targetTab == null) ? Null.NullInteger : targetTab.TabID, tab.TabName)))
            //{
            //    return false;
            //}

            var orgController = new mwHierarchyController();
            orgController.MoveNodeToParent(role, (targetNode == null) ? Null.NullInteger : targetNode.NodeID);

            //ShowSuccessMessage(string.Format(Localization.GetString("TabMoved", LocalResourceFile), tab.TabName));
            return true;  
 
        }

        // TreeView Drag And Drop
        protected void CtlNodeDrop(object sender, RadTreeNodeDragDropEventArgs e)
        {
            //if (PortalSecurity.IsInRole(PortalSettings.AdministratorRoleName))
            //{
                var sourceNode = e.SourceDragNode;
                var destNode = e.DestDragNode;
                var dropPosition = e.DropPosition;
                if (destNode != null)
                {
                    if (sourceNode.TreeView.SelectedNodes.Count <= 1)
                    {
                        PerformDragAndDrop(dropPosition, sourceNode, destNode);
                    }
                    else if (sourceNode.TreeView.SelectedNodes.Count > 1)
                    {
                        foreach (var node in sourceNode.TreeView.SelectedNodes)
                        {
                            PerformDragAndDrop(dropPosition, node, destNode);
                        }
                    }

                    destNode.Expanded = true;

                    foreach (var node in tvMain.GetAllNodes())
                    {
                        node.Selected = node.Value == e.SourceDragNode.Value;
                    }
                }
            //}
        }

        // TreeView Drag And Drop
        private void PerformDragAndDrop(RadTreeViewDropPosition dropPosition, RadTreeNode sourceNode, RadTreeNode destNode)
        {
            var orgController = new mwHierarchyController();
            var sourceNodeToMove = mwHierarchyController.GetHierarchyNode(int.Parse(sourceNode.Value), PortalId, false);
            var targetNodeToMove = mwHierarchyController.GetHierarchyNode(int.Parse(destNode.Value), PortalId, false);

            switch (dropPosition)
            {
                case RadTreeViewDropPosition.Over:
                    if (!(sourceNode.IsAncestorOf(destNode)))
                    {
                        if (MoveNodeToParent(sourceNodeToMove, targetNodeToMove))
                        {
                            sourceNode.Owner.Nodes.Remove(sourceNode);
                            destNode.Nodes.Add(sourceNode);
                        }

                        //ExecuteNonQuery("MoveTabToParent", tabId, GetNull(parentId), lastModifiedByUserID);
                    }
                    break;
                case RadTreeViewDropPosition.Above:
                    if (MoveNode(sourceNodeToMove, targetNodeToMove, Position.Above))
                    {
                        sourceNode.Owner.Nodes.Remove(sourceNode);
                        destNode.InsertBefore(sourceNode);
                    }
                    break;
                case RadTreeViewDropPosition.Below:
                    if (MoveNode(sourceNodeToMove, targetNodeToMove, Position.Below))
                    {
                        sourceNode.Owner.Nodes.Remove(sourceNode);
                        destNode.InsertAfter(sourceNode);
                    }
                    break;
            }
        }
        // ---------------------------------------------------

    }

}